import java.lang.annotation.*;
import java.util.Date;

import static java.lang.annotation.ElementType.*;

/**
 * 自定义注解
 */
public class UserDefinedAnnotation {
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface FristAnnotation {
        /**
         * @interface: 声明和定义注解,意味着 FristAnnotation 实现了java.lang.annotation.Annotation接口
         *     Annotation接口的实现细节都由编译器完成。通过@interface定义注解后，该注解不能继承其他的注解或接口。
         *
         * @Documented: 用来表示该Annotation是否会出现在javadoc中,否则不会出现(默认缺省)
         *     定义Annotation时，@Documented可有可无；若没有定义，则Annotation不会出现在javadoc中。
         *
         * @Target: 用来指定Annotation的类型。表示自定义的注解用于修饰什么的(类,属性,字段,方法等)
         *    ElementType.TYPE:修饰类
         *    ElementType.FIELD:修饰局部变量
         *    ElementType.METHOD:修饰方法
         *    ElementType.PARAMETER:修饰参数
         *    ElementType.CONSTRUCTOR:修饰构造函数
         *    ElementType.LOCAL_VARIABLE:修饰变量
         *    ElementType.ANNOTATION_TYPE:修饰Annotation类型,即修饰注解类型
         *    ElementType.PACKAGE:修饰包
         *    ElementType.TYPE_PARAMETER
         *    ElementType.TYPE_USE
         *
         *    注:定义Annotation时，@Target可有可无。若有@Target，则该Annotation只能用于它所指定的地方；若没有@Target，则该Annotation可以用于任何地方。
         *
         * @Retention: 指定Annotation的策略属性,
         *     @Retention 用来约束注解的生命周期，分别有三个值，源码级别（source），类文件级别（class）或者运行时级别（runtime）
         *     RetentionPolicy.RUNTIME: 注解信息将在运行期(JVM)也保留，因此可以通过反射机制读取注解的信息（源码、class文件和执行的时候都有注解的信息），如SpringMvc中的@Controller、@Autowired、@RequestMapping等。 表示该注解生存期是运行时,将该自定义注解信息保留在.class文件中，并且能被虚拟机读取。
         *     RetentionPolicy.CLASS:注解在class文件中可用，但会被VM丢弃（该类型的注解信息会保留在源码里和class文件里，在执行的时候，不会加载到虚拟机中），请注意，当注解未定义Retention值时，默认值是CLASS，如Java内置注解，@Override、@Deprecated、@SuppressWarnning等
         *     RetentionPolicy.SOURCE:注解将被编译器丢弃（该类型的注解信息只会保留在源码里，源码经过编译后，注解信息会被丢弃，不会保留在编译好的class文件里）

         *     RUNTIME：
         *     注:@Retention可有可无。若没有@Retention，则默认是RetentionPolicy.CLASS。
         *
         * @Deprecated: 当方法或是类上面有@Deprecated注解时，说明该方法或是类都已经过期不建议再用
         *
         *
         * */

        String name() default "";/*声明一个String类型的name元素，其默认值为空字符*/
    }

    @Target({CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Deprecated
    @Documented
    public @interface SecondAnnotation{
        /**
         * java常用的Annotation:
         *     @Deprecated  -- @Deprecated 所标注内容，不再被建议使用。
         *     @Override    -- @Override 只能标注方法，表示该方法覆盖父类中的方法。
         *     @Documented  -- @Documented 所标注内容，可以出现在javadoc中。
         *     @Inherited   -- @Inherited只能被用来标注“Annotation类型”，它所标注的Annotation具有继承性。
         *         @Inherited 可以让注解被继承，但这并不是真的继承，只是通过使用@Inherited，可以让子类Class对象使用getAnnotations()获取父类被@Inherited修饰的注解
         *     @Retention   -- @Retention只能被用来标注“Annotation类型”，而且它被用来指定Annotation的RetentionPolicy属性。
         *     @Target      -- @Target只能被用来标注“Annotation类型”，而且它被用来指定Annotation的ElementType属性。
         *     @SuppressWarnings -- 用于有选择的关闭编译器对类、方法、成员变量、变量初始化的警告
         *         deprecation  -- 使用了不赞成使用的类或方法时的警告
         *         unchecked    -- 执行了未检查的转换时的警告，例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。
         *         fallthrough  -- 当 Switch 程序块直接通往下一种情况而没有 Break 时的警告。
         *         path         -- 在类路径、源文件路径等中有不存在的路径时的警告。
         *         serial       -- 当在可序列化的类上缺少 serialVersionUID 定义时的警告。
         *         finally      -- 任何 finally 子句不能正常完成时的警告。
         *         all          -- 关于以上所有情况的警告。
         *
         * */
    }

    @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface ThirdAnnotation{}

    @ThirdAnnotation
    public class InheritedClass {

    }
    public class InheritedClassSun extends InheritedClass{}


    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface Reference{
        boolean next() default false;
    }

    public @interface AnnotationElementDemo {
        //枚举类型
        enum Status {FIXED,NORMAL};

        //声明枚举
        Status status() default Status.FIXED;

        //布尔类型
        boolean showSupport() default false;

        //String类型
        String name()default "";

        //class类型
        Class<?> testCase() default Void.class;

        //注解嵌套
        Reference reference() default @Reference(next=true);

        //数组类型
        long[] value();
    }

    @Deprecated
    public  void DeprecatedMethod(){

    }

    @Deprecated()
    @SuppressWarnings(value ="all")
    public String DeprecatedFiled="";
    public void CallerDeprecatedMember(){
        this.DeprecatedMethod();
        this.DeprecatedFiled="";
        Long l= Date.parse("yyyy-MM-dd");
    }

}
